package lrg10002.exostention.element.breakdown;

import ic2.api.Direction;
import ic2.api.energy.tile.IEnergySink;

import java.util.List;

import lrg10002.exostention.element.ElementType;
import lrg10002.exostention.element.ItemMakeupManager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;

public class TileEntityBreakdown extends TileEntity implements IInventory, IEnergySink {

	public TileEntityBreakdown() {

	}

	public int ticksRemaining = 0;
	public int power = 0;
	public boolean inEnergyNetwork = false;
	public static final int MAX_STORAGE = 128000;

	public ItemStack[] inv = new ItemStack[17];

	@Override
	public int getSizeInventory() {
		return inv.length;
	}

	@Override
	public ItemStack getStackInSlot(int var1) {
		return inv[var1];
	}

	@Override
	public ItemStack decrStackSize(int slot, int amt) {
		ItemStack stack = getStackInSlot(slot);
		if (stack != null) {
			if (stack.stackSize <= amt) {
				setInventorySlotContents(slot, null);
			} else {
				stack = stack.splitStack(amt);
				if (stack.stackSize == 0) {
					setInventorySlotContents(slot, null);
				}
			}
		}
		return stack;
	}

	@Override
	public ItemStack getStackInSlotOnClosing(int slot) {
		ItemStack stack = getStackInSlot(slot);
		if (stack != null) {
			setInventorySlotContents(slot, null);
		}
		return stack;
	}

	@Override
	public void setInventorySlotContents(int slot, ItemStack stack) {
		inv[slot] = stack;
		if (stack != null && stack.stackSize > getInventoryStackLimit()) {
			stack.stackSize = getInventoryStackLimit();
		}
	}

	@Override
	public String getInvName() {
		return "exo_breakdownunit_inv";
	}

	@Override
	public int getInventoryStackLimit() {
		return 64;
	}

	@Override
	public boolean isUseableByPlayer(EntityPlayer player) {
		return worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this
				&& player.getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) < 64;
	}

	@Override
	public void readFromNBT(NBTTagCompound tagCompound) {
		super.readFromNBT(tagCompound);

		NBTTagList tagList = tagCompound.getTagList("Inventory");
		for (int i = 0; i < tagList.tagCount(); i++) {
			NBTTagCompound tag = (NBTTagCompound) tagList.tagAt(i);
			byte slot = tag.getByte("Slot");
			if (slot >= 0 && slot < inv.length) {
				inv[slot] = ItemStack.loadItemStackFromNBT(tag);
			}
		}
	}

	@Override
	public void writeToNBT(NBTTagCompound tagCompound) {
		super.writeToNBT(tagCompound);

		NBTTagList itemList = new NBTTagList();
		for (int i = 0; i < inv.length; i++) {
			ItemStack stack = inv[i];
			if (stack != null) {
				NBTTagCompound tag = new NBTTagCompound();
				tag.setByte("Slot", (byte) i);
				stack.writeToNBT(tag);
				itemList.appendTag(tag);
			}
		}
		tagCompound.setTag("Inventory", itemList);
	}

	@Override
	public void updateEntity() {

		if (worldObj.isRemote) {
			if (ticksRemaining > 0 && power > 128) {
				ticksRemaining--; // server side
				power -= 128;
			}
			if (ticksRemaining == 0 && (inv[0] != null && inv[0].stackSize > 0)) {
				// it finished converting!

				int put = 0;
				List<ElementType> rec = ItemMakeupManager.cont.getMakeup(inv[0]).grid;
				if (rec == null) {
					return;
				}
				for (int x = 1; x < 17; x++) {
					ItemStack is = inv[x];
					if (is == null
							|| (ElementType.areElementsEqual(is, rec.get(x).getItemStack()) && is.stackSize
									+ rec.get(x).getItemStack().stackSize <= rec.get(x).getItemStack().getMaxStackSize())
							|| rec.get(x) == ElementType.EMPTY) {
						// is the slot empty, or is the slot equal and has
						// enough room, or is slot not used in recipe?
						put++;
					}
				}
				if (put >= 16) {
					inv[0].stackSize--;
					if (inv[0].stackSize <= 0)
						inv[0] = null;
					for (int x = 1; x < 17; x++) {
						if (inv[x] == null) {
							inv[x] = rec.get(x).getItemStack();
						} else {
							if (rec.get(x) != ElementType.EMPTY
									&& ElementType.areElementsEqual(inv[x], rec.get(x).getItemStack())) {
								// this spot is used, and same element
								inv[x].stackSize++;
							}
						}
					}

				}

			}
			if (inv[0] != null && inv[0].stackSize > 0) {
				ticksRemaining = getTime(inv[0]);
			}
			
		}

		if (ticksRemaining > 0 && power > 128) {
			ticksRemaining--; // client side
			power -= 128;
		}
	}

	public int getTime(ItemStack i) {
		return 20;
	}

	@Override
	public void openChest() {

	}

	@Override
	public void closeChest() {

	}

	@Override
	public boolean acceptsEnergyFrom(TileEntity emitter, Direction direction) {
		return power < MAX_STORAGE;
	}

	@Override
	public boolean isAddedToEnergyNet() {
		return inEnergyNetwork;
	}

	@Override
	public int demandsEnergy() {
		return 128;
	}

	@Override
	public int injectEnergy(Direction directionFrom, int amount) {
		if (power == MAX_STORAGE) {
			return amount;
		} else if (power + amount > MAX_STORAGE) {
			int ba = power + amount;
			int leftover = ba - MAX_STORAGE;
			power = MAX_STORAGE;
			return leftover;
		} else {
			power += amount;
			return 0;
		}
	}

	@Override
	public int getMaxSafeInput() {
		return Integer.MAX_VALUE;
	}

}
